﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Minio;
using Minio.DataModel;
using Minio.DataModel.Args;
using Newtonsoft.Json;

namespace Upload.API.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class FileUploadController : ControllerBase
    {
        private readonly IMinioClient _minioClient;
        private string bucketName = "images";

        public FileUploadController()
        {
            _minioClient = new MinioClient()
                .WithEndpoint("59.110.123.186:9000")       // MinIO 服务器的端点地址为 "10.31.60.18:9000"
                .WithCredentials("admin", "admin123")   // MinIO 服务器连接所需的凭据，包括用户名和密码
                .WithSSL(false)                         // MinIO 服务器是否启用 SSL 加密通信
                .Build();                               // MinIO 服务器配置完成，构建 MinioClient 实例
        }

        [HttpGet]
        public async Task<IActionResult> ListBuckets()
        {
            // ListBucketsAsync() 来获取 MinIO 服务器上的所有存储桶 (buckets
            // ConfigureAwait(false) 的作用是防止异步操作回到调用线程上继续执行，以避免死锁。
            var buckets = await _minioClient.ListBucketsAsync().ConfigureAwait(false);
            return Ok(buckets);
        }

        /// <summary>
        /// 上传单个文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            // 检查桶是否存在
            var beArgs = new BucketExistsArgs()
                .WithBucket(bucketName);
            bool found = await _minioClient.BucketExistsAsync(beArgs);

            // 如果桶不存在，则创建桶
            if (!found)
            {
                var mbArgs = new MakeBucketArgs()
                    .WithBucket(bucketName);
                await _minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
            }

            // 获取文件名，加入全球唯一标识
            var objectName = $"{Guid.NewGuid()}_{file.FileName}";

            // 使用流数据上传文件
            var putArgs = new PutObjectArgs()
                .WithBucket(bucketName)
                .WithObject(objectName)
                .WithStreamData(file.OpenReadStream())
                .WithContentType(file.ContentType)
                .WithObjectSize(file.Length);
            await _minioClient.PutObjectAsync(putArgs).ConfigureAwait(false);

            // 直接拼接公开URL
            var url = $"http://59.110.123.186:9000/{bucketName}/{objectName}";
            return Ok(url);
        }

        /// <summary>
        /// 上传多个文件
        /// </summary>
        /// <param name="formFiles">要上传的文件集合</param>
        /// <returns>返回上传成功的文件名列表</returns>
        [HttpPost]
        public async Task<IActionResult> UploadFiles(IFormFileCollection formFiles)
        {
            // 检查存储桶是否存在
            var beArgs = new BucketExistsArgs()
                .WithBucket(bucketName);
            bool found = await _minioClient.BucketExistsAsync(beArgs);

            // 如果桶不存在则创建
            if (!found)
            {
                var mbArgs = new MakeBucketArgs()
                    .WithBucket(bucketName);
                await _minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
            }

            var uploadedFileUrls = new List<string>();
            foreach (var formFile in formFiles)
            {
                using var stream = formFile.OpenReadStream();

                // 获取文件名，加入全球唯一标识
                var objectName = $"{Guid.NewGuid()}_{formFile.FileName}";

                // 上传文件到MinIO
                var putArgs = new PutObjectArgs()
                    .WithBucket(bucketName)
                    .WithObject(objectName)
                    .WithStreamData(stream)
                    .WithContentType(formFile.ContentType)
                    .WithObjectSize(stream.Length);

                await _minioClient.PutObjectAsync(putArgs).ConfigureAwait(false);

                // 直接拼接公开URL
                var url = $"http://59.110.123.186:9000/{bucketName}/{objectName}";
                uploadedFileUrls.Add(url);
            }

            // 以逗号分隔字符串返回
            var result = string.Join(",", uploadedFileUrls);
            return Ok(result);
        }
    }
}

